﻿Namespace Global.MS.Internal.Threading

    Public Delegate Function CatchExceptionDelegate(ByVal source As Object, ByVal e As Exception, ByVal catchHandler As [Delegate]) As Boolean
    Public Delegate Function FilterExceptionDelegate(ByVal source As Object, ByVal e As Exception) As Boolean
    Public Delegate Function InternalRealCallDelegate(ByVal method As [Delegate], ByVal args As Object, ByVal numArgs As Integer) As Object

    Public NotInheritable Class ExceptionFilterHelper

        Private _catchException As CatchExceptionDelegate
        Private _filterException As FilterExceptionDelegate
        Private _internalRealCall As InternalRealCallDelegate

        Public Sub New(ByVal internalRealCall As InternalRealCallDelegate, ByVal filterException As FilterExceptionDelegate, ByVal catchException As CatchExceptionDelegate)
            Me._internalRealCall = internalRealCall
            Me._filterException = filterException
            Me._catchException = catchException
        End Sub

        Public Function TryCatchWhen(ByVal source As Object, ByVal method As [Delegate], ByVal args As Object, ByVal numArgs As Integer, ByVal catchHandler As [Delegate]) As Object
            Dim result As Object = Nothing
            Try
                result = Me._internalRealCall.Invoke(method, args, numArgs)
            Catch exception As Exception
                If Not Me._catchException(source, exception, catchHandler) Then
                    Throw exception
                End If
            End Try
            Return result
        End Function

    End Class

End Namespace